﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using TomanuExtensions;

namespace AmiEmuLib.Configuration.KnownRomConfig
{
    /// <summary>
    /// Copied from WinUAE. Readed from Roms.xml. 
    /// </summary>
    [DebuggerDisplay("KnownRom, Name = {Name}, Exists = {Exists}")]
    public class KnownRom : UnknownRom
    {
        /// <summary>
        /// ROM name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        ///Version (1.3, 2.0, etc).
        /// </summary>
        public string Version { get; set; }

        /// <summary>
        /// Subrevision (40.56, etc). 
        /// </summary>
        public string Build { get; set; }

        /// <summary>
        /// Hardware type for which Roms was designed.
        /// </summary>
        public HardwareType HardwareType { get; set; }

        /// <summary>
        /// Special requirements for ROM.
        /// </summary>
        public RomRequirements Requirements { get; set; }

        /// <summary>
        /// Thera are many kickstart. But this one are important (probably most popular). 
        /// Used in quickstart and when showing not all roms.
        /// </summary>
        public RomType RomTypes { get; set; }

        /// <summary>
        /// Only AmigaModelRoms with priority higher than -1 are used as defaults.
        /// Rom with higher prority is taken first. 
        /// Priorities can take any numbers from -1 up.
        /// </summary>
        public int Priority { get; set; }

        /// <summary>
        /// Size of rom in bytes.
        /// </summary>
        public MemorySize Size { get; set; }

        /// <summary>
        /// Rom type. Here you can separate kickstarts, ar's, bioses, extended roms etc.
        /// </summary>
        public RomProperties RomProperties { get; set; }

        /// <summary>
        /// Some roms are split in two parts, even and odd bytes.
        /// </summary>
        public int EvenOddGroupID { get; set; }

        /// <summary>
        /// CRC32 of rom. Try to use SHA1.
        /// </summary>
        public string CRC32 { get; set; }

        /// <summary>
        /// Constructor.
        /// </summary>
        internal KnownRom(XmlReader a_reader)
        {
            ReadXml(a_reader);
        }

        /// <summary>
        /// Read xml.
        /// </summary>
        /// <param name="a_reader"></param>
        private void ReadXml(XmlReader a_reader)
        {
            Name = a_reader.GetAttribute("Name");

            a_reader.ReadStartElement(GetType().Name);

            Version = a_reader.ReadElementString("Version");
            Build = a_reader.ReadElementString("Build");
            RomTypes = a_reader.ReadElementContentAsEnum<RomType>("RomTypes");
            HardwareType = a_reader.ReadElementContentAsEnum<HardwareType>("HardwareType");
            Requirements = a_reader.ReadElementContentAsEnum<RomRequirements>("Requirements");
            RomProperties = a_reader.ReadElementContentAsEnum<RomProperties>("RomProperties");
            Priority = a_reader.ReadElementContentAsInt("Priority");
            Size = a_reader.ReadElementString("Size");
            EvenOddGroupID = a_reader.ReadElementContentAsInt("EvenOddGroupID");
            CRC32 = a_reader.ReadElementString("CRC32");
            SHA1 = a_reader.ReadElementString("SHA1");

            a_reader.ReadEndElement();
        }

        /// <summary>
        /// Write xml.
        /// </summary>
        /// <param name="a_writer"></param>
        internal void WriteXml(XmlWriter a_writer)
        {
            a_writer.WriteStartElement(GetType().Name);

            a_writer.WriteAttributeString("Name", Name);
            a_writer.WriteElement("Version", Version);
            a_writer.WriteElement("Build", Build);
            a_writer.WriteElementEnum<RomType>("RomTypes", RomTypes);
            a_writer.WriteElementEnum<HardwareType>("HardwareType", HardwareType);
            a_writer.WriteElementEnum<RomRequirements>("Requirements", Requirements);
            a_writer.WriteElementEnum<RomProperties>("RomProperties", RomProperties);
            a_writer.WriteElement("Priority", Priority);
            a_writer.WriteElement("Size", Size);
            a_writer.WriteElement("EvenOddGroupID",EvenOddGroupID );
            a_writer.WriteElement("CRC32", CRC32);
            a_writer.WriteElement("SHA1", SHA1);

            a_writer.WriteEndElement();
        }

        /// <summary>
        /// Is rom exists.
        /// </summary>
        public bool Exists
        {
            get
            {
                return FilePath != String.Empty;
            }
        }
    }
}
